/*
Copyright (c) 2025 HeZongLun
NahidaProject is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan
PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/

#include "SignalAndSlot.h"

inline void NahidaProject::SignalAndSlot::Connection::Disconnect() {
	if (key_ && key_->signal != nullptr) {
		key_->signal->Disconnect(Connection::CalculateHash(key_));
	}
}

inline bool NahidaProject::SignalAndSlot::Connection::Connected() const {
	return key_ && key_->signal != nullptr;
}

void NahidaProject::SignalAndSlot::ScopedConnections::operator+=(const Connection& connection) {
	connections_.emplace_back(connection);
}

void NahidaProject::SignalAndSlot::ScopedConnections::operator+=(std::initializer_list<Connection> connections) {
	connections_.insert(connections_.end(), connections.begin(), connections.end());
}

void NahidaProject::SignalAndSlot::ScopedConnections::Clear() {
	for (auto& connection : connections_) {
		connection.Disconnect();
	}
	connections_.clear();
}

void NahidaProject::SignalAndSlot::ScopedConnections::CleanUp() {
	std::erase_if(connections_, [](Connection& connection) {
		return !connection.Connected();
		});
}

int NahidaProject::SignalAndSlot::ScopedConnections::Size() const {
	return static_cast<int>(connections_.size());
}

NahidaProject::SignalAndSlot::ScopedConnection& NahidaProject::SignalAndSlot::ScopedConnection::operator=(const Connection& connection) {
	connection_.Disconnect();
	connection_ = connection;
	return *this;
}

void NahidaProject::SignalAndSlot::ScopedConnection::Disconnect() {
	connection_.Disconnect();
}

bool NahidaProject::SignalAndSlot::ScopedConnection::Connected() const {
	return connection_.Connected();
}

void NahidaProject::SignalAndSlot::ScopedConnection::Release() {
	connection_ = {};
}